package org.qdao.util;

import java.lang.reflect.Field;
import java.util.ArrayList;
import java.util.List;

import org.qdao.TableDescriptor;
import org.qdao.annotation.Column;
import org.qdao.annotation.Column.DBColumnType;
import org.qdao.annotation.PrimaryKey;
import org.qdao.annotation.Table;

import com.tan.util.StringUtil;

/**
 * 
 * @author TanYuanji
 *
 */
public final class SQLTigger {

	/**
	 * <pre>
	 * 	analysis the table for the class of the model 
	 *  
	 *  解析目标模型的表结构
	 * </pre>
	 * 
	 * @author tan
	 * @param tableClazz
	 * @return 2010/02/25 10:41:42
	 */
	public static TableDescriptor getTableDescriptor(Class<?> tableClazz) {
		// TODO : use reflect to get annotation from table class
		TableDescriptor tableDescriptor = new TableDescriptor();

		Table table = (Table) tableClazz.getAnnotation(Table.class);
		if (table != null) {
			tableDescriptor.name = table.name();
			tableDescriptor.description = table.description();
		}

		Field[] fields = tableClazz.getDeclaredFields();
		List<TableDescriptor.ColumnDescription> columnDescriptors =
				new ArrayList<TableDescriptor.ColumnDescription>();

		List<String> primaryKeys = new ArrayList<String>();

		for (int i = 0; i < fields.length; i++) {
			Column column = fields[i].getAnnotation(Column.class);
			if (column != null) {
				TableDescriptor.ColumnDescription columnDescription = new TableDescriptor.ColumnDescription();
				columnDescription.decimal = column.decimal();
				columnDescription.description = column.description();
				columnDescription.name = column.name();
				columnDescription.length = column.length();
				columnDescription.nullable = column.nullable();
				columnDescription.type = column.type();
				columnDescriptors.add(columnDescription);
			}
			PrimaryKey primaryKey = fields[i].getAnnotation(PrimaryKey.class);
			if (primaryKey != null) {
				primaryKeys.add(column.name());
			}
		}

		// set the columns
		tableDescriptor.columns =
				columnDescriptors.toArray(
				new TableDescriptor.ColumnDescription[columnDescriptors.size()]);
		tableDescriptor.primaryKeys = primaryKeys.toArray(new String[primaryKeys.size()]);
		return tableDescriptor;
	}

	/**
	 * 
	 * <pre>
	 * 	the tigger for the creater of table
	 *  
	 *  解析目标表结构的创建表的结构的sql语句
	 * </pre>
	 * 
	 * 
	 * 
	 * @author tan
	 * @param table
	 * @return 2010/02/25 10:41:21
	 */
	public static String getOracleCreateTigger(TableDescriptor table) {
		StringBuffer buf = new StringBuffer("CREATE TABLE ");
		// add the table name
		buf.append(table.name + "(\r\n");
		for (int i = 0; i < table.columns.length; i++) {
			// add the column's name
			buf.append("\t" + table.columns[i].name + ' ')
								// add the column's type
					.append(table.columns[i].type);
			// add the column's length
			if (table.columns[i].length != -1) {
				buf.append("(" + table.columns[i].length + ") ");
			} else {
				buf.append(' ');
			}
			// add the column's nullable
			if (!table.columns[i].nullable) {
				buf.append("NOT NULL");
			}
			
			// add the comment for the field of the table.
			if ( StringUtil.isNotEmpty( table.columns[i].description ) ) {
				buf.append( " COMMENT '" + table.columns[i].description  + "'");
			}
			// add the comma
			if (i == table.columns.length - 1 && table.primaryKeys.length == 0) {
				buf.append("\r\n");
			} else {
				buf.append(",\r\n");
			}
		}
		// add the constraint for primary key
		if (table.primaryKeys.length != 0) {
			buf.append("\tCONSTRAINT PK_").append(table.name).append(" PRIMARY KEY (");
		}
		// add the primary key
		for (int i = 0; i < table.primaryKeys.length; i++) {
			if (i != table.primaryKeys.length - 1) {
				buf.append(table.primaryKeys[i]).append(',');
			} else {
				buf.append(table.primaryKeys[i]).append(")\r\n");
			}
		}
		// close the DDL language
		buf.append(')');

		// add the comment

		// if (table.description != null && !"".equals(table.description)) {
		// buf.append("\r\n/\r\nCOMMENT ON TABLE ").append(table.name)
		// .append(" IS ").append("'").append(table.description).append("'\r\n/");
		// } else {
		// buf.append("\r\n");
		// }
		// for (int i = 0; i < table.columns.length; i++) {
		// if (table.columns[i].description != null &&
		// !"".equals(table.columns[i].description)) {
		// buf.append("\r\nCOMMENT ON COLUMN  ").append(table.name).append(".").append(table.columns[i].name)
		// .append(" IS ").append("'").append(table.columns[i].description).append(
		// "'\r\n/");
		// }
		// }
		return buf.toString();
	}

	/**
	 * 
	 * <pre>
	 * 	the tigger for the creater of table
	 *  
	 *  解析目标表结构的创建表的结构的sql语句
	 * </pre>
	 * 
	 * 
	 * 
	 * @author tan
	 * @param table
	 * @return 2010/02/25 10:41:21
	 */

	/**
	 * 
	 * <pre>
	 * 	the tigger for the creater of table
	 *  
	 *  解析目标表结构的创建表的结构的sql语句
	 * </pre>
	 * 
	 * 
	 * 
	 * @author tan
	 * @param table
	 * @return 2010/02/25 10:41:21
	 */
	public static String getMySqlCreateTigger(final TableDescriptor table) {
		StringBuffer buf = new StringBuffer("CREATE TABLE IF NOT EXISTS ");
		// add the table name
		buf.append(table.name + "(\r\n");
		for (int i = 0; i < table.columns.length; i++) {
			// add the column's name

			if (
					table.columns[i].type == DBColumnType.INTEGER && 
					table.columns[i].autoIncrement
				) {
				buf.append("\t" + table.columns[i].name +
						' ').append(" INT NOT NULL AUTO_INCREMENT"
						);
				
				// add the comment for the field of the table.
				if ( StringUtil.isNotEmpty( table.columns[i].description ) ) {
					buf.append( " COMMENT '" + table.columns[i].description  + "'");
				}
				
				buf.append(",\r\n");
				continue;
			}

			buf.append("\t" + table.columns[i].name + ' ')
								// add the column's type
					.append(table.columns[i].type);
			// add the column's length
			if (table.columns[i].length != -1) {
				buf.append("(" + table.columns[i].length);
				// add the decimal
				if (table.columns[i].decimal != 0) {
					buf.append("," + table.columns[i].decimal);
				}
				buf.append(')');
			} else {
				buf.append(' ');
			}
			// add the column's nullable
			if (!table.columns[i].nullable) {
				buf.append(" NOT NULL");
			}
			
			// add the default value.
			if ( StringUtil.isNotEmpty( table.columns[i].defaultValue ) ) {
				buf.append(" DEFAULT " + table.columns[i].defaultValue);
			}
			
			// add the comment for the field of the table.
			if ( StringUtil.isNotEmpty( table.columns[i].description ) ) {
				buf.append( " COMMENT '" + table.columns[i].description  + "'");
			}
			
			// add the comma
			if (i == table.columns.length - 1) {
				if (table.primaryKeys.length != 0) {
					buf.append(",\r\n");
				} else
					buf.append("\r\n");
			} else {
				buf.append(",\r\n");
			}
		}
		// add the constraint for primary key
		if ( null  != table.primaryKeys && table.primaryKeys.length != 0) {
			buf.append("\tCONSTRAINT PK_").append(table.name).append(" PRIMARY KEY (");
			
			// add the primary key
			for (int i = 0; i < table.primaryKeys.length; i++) {
				if (i != table.primaryKeys.length - 1) {
					buf.append(table.primaryKeys[i]).append(',');
				} else {
					buf.append(table.primaryKeys[i]).append(")");
				}
			}
		}

		// close the DDL language
		return buf.append("\r\n)").toString();
	}
}
